import {
  Inject,
  Controller,
  Body,
  UseGuard,
  Post,
  Query,
  Get,
  Put,
} from '@midwayjs/core';
import { Context } from '@midwayjs/koa';
import { DepartmentService } from '../service/api.department.service';
import {
  DepartmentDTO,
  NewDirectorIdDTO,
  UserIdDTO,
  UpdateDepartmentDTO,
  DepartmentIdDTO,
} from '../dto/department';
import { PageDTO } from '../dto/page';
import { DoctorGuard } from '../guard/doctor.guard';
import { DirectorGuard } from '../guard/director.guard';
import { AuthGuard } from '../guard/auth.guard';
@Controller('/department')
export class DepartmentController {
  @Inject()
  departmentService: DepartmentService;
  @Inject()
  ctx: Context;
  /**
   * @name getDepartments 获取所有科室
   * @description get /api/department/getdepartments
   * @returns {object} departments - 所有科室
   */
  @Get('/getDepartments')
  async getDepartments(): Promise<object> {
    // 获取所有科室
    return await this.departmentService.getDepartments();
  }
  /**
   * @name addDepartment 添加科室
   * @description post /api/department/adddepartment
   * @param {DepartmentDto} departmentDto - 科室信息
   * @returns {object} 添加成功
   */
  @Post('/addDepartment')
  async addDepartment(@Body() departmentDto: DepartmentDTO): Promise<boolean> {
    if (this.ctx.state.user.departmentId) {
      throw new Error('您已经加入科室，请先退出科室再创建');
    }
    const { departmentName } = departmentDto;
    // 查看有没有该科室
    const user = await this.departmentService.findDepartment(
      'user_id',
      this.ctx.state.user.userId
    );
    if (user) {
      throw new Error('您已经创建过科室，不能再创建');
    }
    const department = await this.departmentService.findDepartment(
      'name',
      departmentName
    );
    if (department) {
      throw new Error('该科室已经存在');
    }
    return await this.departmentService.addDepartment(departmentName);
  }
  /**
   * @name   getMyDepartment 获取我的科室信息
   * @description get /api/department/getmydepartment
   * @param  {PageDTO} pageDto 科室信息DTO
   * @return {object} 我的科室信息
   */
  @UseGuard(DoctorGuard)
  @Get('/getMyDepartment')
  async getMyDepartment(@Query() pageDto: PageDTO): Promise<object> {
    const departmentId = this.ctx.state.user.departmentId;
    return await this.departmentService.getMyDepartment(departmentId, pageDto);
  }
  /**
   * @name   exitDepartment 退出科室
   * @description post /api/department/exitdepartment
   * @returns {object} 退出成功
   */
  @UseGuard(DoctorGuard)
  @Put('/exitDepartment')
  async exitDepartment(): Promise<boolean> {
    if (this.ctx.state.user.directorFlag == 1) {
      throw new Error('您是科室主任，请转移权限或者直接解散科室');
    }
    const userId = this.ctx.state.user.userId;
    const departmentId = this.ctx.state.user.departmentId;
    return await this.departmentService.exitDepartment(userId, departmentId);
  }
  /**
   * @name   delDepartment 解散科室
   * @description post /api/department/deldepartment
   * @returns {boolean} 解散成功
   */
  @UseGuard(DirectorGuard)
  @UseGuard(DoctorGuard)
  @Put('/delDepartment')
  async delDepartment(): Promise<boolean> {
    return await this.departmentService.delDepartment();
  }
  /**
   * @name   replaceDirector 主任转移权限
   * @description post /api/department/replacedirector
   * @param  {NewDirectorIdDTO} newDirectorId 新主任id
   * @return {boolean} 转移成功
   */
  @UseGuard(DirectorGuard)
  @UseGuard(DoctorGuard)
  @Put('/replaceDirector')
  async replaceDirector(
    @Body() newDirectorIdDto: NewDirectorIdDTO
  ): Promise<boolean> {
    const { newDirectorId } = newDirectorIdDto;
    const departmentId = this.ctx.state.user.departmentId;
    const user = await this.departmentService.findDepartmentMember(
      newDirectorId,
      departmentId
    );
    console.log(user);
    if (!user) {
      throw new Error('该用户不在该科室');
    }
    return await this.departmentService.replaceDirector(
      newDirectorIdDto,
      departmentId
    );
  }
  /**
   * @name  getAdminDepartments 管理员获取所有科室信息
   * @description get /api/department/getAdminDepartments
   * @param  {PageDTO} pageDto
   * @returns {object} 所有科室信息
   */
  @UseGuard(AuthGuard)
  @Get('/getAdminDepartments')
  async getAdminDepartments(@Query() pageDto: PageDTO): Promise<object> {
    return await this.departmentService.getAdminDepartments(pageDto);
  }
  /**
   * @name  getDepartmentMember 管理员查找科室成员
   * @description get /api/department/getDepartmentMember
   * @param  {DepartmentIdDTO} departmentId 科室id
   * @returns {object} 科室成员信息
   */
  @UseGuard(AuthGuard)
  @Get('/getDepartmentMember')
  async getDepartmentMember(
    @Query() departmentIdDto: DepartmentIdDTO
  ): Promise<object> {
    const { departmentId } = departmentIdDto;
    const department = await this.departmentService.findDepartment(
      'id',
      departmentId
    );
    if (!department) {
      throw new Error('该科室不存在,或者已经失效的科室没有成员');
    }
    return await this.departmentService.getDepartmentMember(departmentId);
  }
  /**
   * @name  adminDelDepartmentMember 管理员删掉该科室成员
   * @description put /api/department/adminDelDepartmentMember
   * @param  {DepartmentIdDTO} departmentId 科室id
   * @param  {UserIdDTO} userIdDTO 用户id
   * @returns {boolean} 删除成功
   */
  @UseGuard(AuthGuard)
  @Put('/adminDelDepartmentMember')
  async adminDelDepartmentMember(
    @Body() userIdDto: UserIdDTO
  ): Promise<boolean> {
    if (!userIdDto.departmentId) {
      throw new Error('departmentId参数不能为空');
    }
    const { departmentId, userId } = userIdDto;
    const department = await this.departmentService.findDepartment(
      'id',
      departmentId
    );
    if (!department) {
      throw new Error('该科室不存在,或者已经失效的科室没有成员');
    }
    const user = await this.departmentService.findDepartmentMember(
      userId,
      departmentId
    );
    if (!user) {
      throw new Error('该用户不在该科室');
    }
    return await this.departmentService.exitDepartment(userId, departmentId);
  }
  /**
   * @name directorDelDepartmentMember 主任删掉该科室成员
   * @description put /api/department/directorDelDepartmentMember
   * @param  {UserIdDTO} userIdDTO 用户id
   * @returns {boolean} 删除成功
   */
  @UseGuard(DirectorGuard)
  @UseGuard(DoctorGuard)
  @Put('/directorDelDepartmentMember')
  async directorDelDepartmentMember(
    @Body() userIdDTO: UserIdDTO
  ): Promise<boolean> {
    const { userId } = userIdDTO;
    const departmentId = this.ctx.state.user.departmentId;
    const user = await this.departmentService.findDepartmentMember(
      userId,
      departmentId
    );
    if (!user) {
      throw new Error('该用户不在该科室');
    }
    return await this.departmentService.exitDepartment(userId, departmentId);
  }
  /**
   * @name  adminUpdateDepartment 管理员修改科室信息
   * @description put /api/department/adminUpdateDepartment
   * @param  {UpdateDepartmentDTO} updateDepartmentDto 科室信息
   * @returns {boolean} 修改成功
   */
  @UseGuard(AuthGuard)
  @Put('/adminUpdateDepartment')
  async adminUpdateDepartment(
    @Body() updateDepartmentDto: UpdateDepartmentDTO
  ): Promise<boolean> {
    if (!updateDepartmentDto.departmentId) {
      throw new Error('departmentId参数不能为空');
    }
    const filteredData = Object.entries(updateDepartmentDto).reduce(
      (acc, [key, value]) => {
        if (value != null) {
          // 同时过滤掉 null 和 undefined
          acc[key] = value;
        }
        return acc;
      },
      {} as UpdateDepartmentDTO
    );
    if (Object.keys(filteredData).length === 1) {
      throw new Error('更新数据为空');
    }
    if (filteredData.name) {
      const departmentName = await this.departmentService.findDepartment(
        'name',
        filteredData.name
      );
      if (departmentName) {
        throw new Error('该科室已经存在');
      }
    }
    return await this.departmentService.updateDepartment(filteredData);
  }
  /**
   * @name  updateDepartment 科室主任修改科室名称
   * @description put /api/department/updateDepartment
   * @param  {UpdateDepartmentDTO} updateDepartmentDto 科室信息
   * @returns {boolean} 修改成功
   */
  @UseGuard(DirectorGuard)
  @UseGuard(DoctorGuard)
  @Put('/updateDepartment')
  async updateDepartment(
    @Body() updateDepartmentDto: UpdateDepartmentDTO
  ): Promise<boolean> {
    updateDepartmentDto.validFlag = null;
    updateDepartmentDto.departmentId = this.ctx.state.user.departmentId;
    const filteredData = Object.entries(updateDepartmentDto).reduce(
      (acc, [key, value]) => {
        if (value != null) {
          acc[key] = value;
        }
        return acc;
      },
      {} as UpdateDepartmentDTO
    );
    if (Object.keys(filteredData).length === 1) {
      throw new Error('更新数据为空');
    }
    const { departmentId } = filteredData;
    const department = await this.departmentService.findDepartment(
      'id',
      departmentId
    );
    if (!department) {
      throw new Error('该科室不存在');
    }
    if (filteredData.name) {
      const departmentName = await this.departmentService.findDepartment(
        'name',
        filteredData.name
      );
      if (departmentName) {
        throw new Error('该科室已经存在');
      }
    }
    return await this.departmentService.updateDepartment(filteredData);
  }
  /**
   * @name  adminSetDirector 管理员设置科室主任
   * @description put /api/department/adminSetDirector
   * @param  {UserIdDTO} userIdDTO 用户id
   * @returns {boolean} 设置成功
   */
  @UseGuard(AuthGuard)
  @Put('/adminSetDirector')
  async adminSetDirector(@Body() userIdDTO: UserIdDTO): Promise<boolean> {
    if (!userIdDTO.departmentId) {
      throw new Error('departmentId参数不能为空');
    }
    const { departmentId, userId } = userIdDTO;
    const department = await this.departmentService.findDepartment(
      'id',
      departmentId
    );
    if (!department) {
      throw new Error('该科室不存在');
    }
    const user = await this.departmentService.findDepartmentMember(
      userId,
      departmentId
    );
    if (!user) {
      throw new Error('该用户不在该科室');
    }
    return await this.departmentService.adminSetDirector(userId, departmentId);
  }
}
